"use strict";
// 得到当前样式值方法
function __getStyleValue(elem, prop) {
    return window.getComputedStyle(elem, null).getPropertyValue(prop);
}
// 计算当前文档滚动值对象方法
function __getDocScrollValue() {
    return {
        scrollX: document.documentElement.scrollLeft || window.pageXOffset || document.body.scrollLeft,
        scrollY: document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop,
    };
}
// 设置透明度方法
function __setOpacity(elem, opacity) {
    if (typeof opacity === "string") {
        opacity = parseFloat(opacity) / 100;
        elem.style.opacity = opacity.toString();
    }
    else {
        elem.style.opacity = opacity.toString();
    }
}
// 元素设置淡入效果
function __setFadeIn(elem, speed) {
    if (speed > 100) {
        // 安全校验
        console.warn("输入的速率数值大于100，请检查输入的速率值是否合理。");
    }
    __setOpacity(elem, 0); // 保证元素默认的透明度
    var timer = 0; // 计时器
    var opacity = 0;
    function step() {
        if (opacity >= 100) {
            window.cancelAnimationFrame(timer);
        }
        else {
            opacity += speed;
            __setOpacity(elem, opacity / 100);
            window.requestAnimationFrame(step);
        }
    }
    window.requestAnimationFrame(step); // 调用动画函数
}
// 元素设置淡出效果
function __setFadeOut(elem, speed) {
    if (speed > 100) {
        // 安全校验
        console.warn("输入的速率数值大于100，请检查输入的速率值是否合理。");
    }
    __setOpacity(elem, "100");
    var opacity = 100;
    var timer = 0;
    function step() {
        if (opacity <= 0) {
            window.cancelAnimationFrame(timer);
            // 动画结束后向事件管理器发出结束信号，清空回调
            em.trigger('fadeOutDone');
        }
        else {
            opacity -= speed;
            __setOpacity(elem, opacity / 100);
            window.requestAnimationFrame(step);
        }
    }
    window.requestAnimationFrame(step);
}
// 为元素设置样式方法
function _addClass(elem, class_name) {
    if (elem.classList == undefined) {
        // 退化方法
        var classList = elem.className.split(" ");
        if (classList.indexOf(class_name) === -1) {
            classList.push(class_name);
        }
        elem.className = classList.join(" ");
    }
    else {
        elem.classList.add(class_name);
    }
}
// 为元素移除样式方法
function _removeClass(elem, class_name) {
    console.log('emit'); // 测试
    if (elem.classList == undefined) {
        // 退化方法
        var classList = elem.className.split(" ");
        var removeIndex = classList.indexOf(class_name);
        if (removeIndex > -1) {
            classList.splice(removeIndex, 1);
        }
        elem.className = classList.join(" ");
    }
    else {
        elem.classList.remove(class_name);
    }
}
// 混入方法
function _mixin(target) {
    var objs = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        objs[_i - 1] = arguments[_i];
    }
    var _loop_1 = function (i) {
        Object.keys(objs[i]).forEach(function (key) {
            target[key] = objs[i][key];
        });
    };
    for (var i = 0; i < objs.length; i++) {
        _loop_1(i);
    }
    return target;
}
// 节流方法
function _throttle(callback, delay) {
    var timer = 0;
    var throttled = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        var _this = this;
        clearTimeout(timer);
        timer = setTimeout(function () {
            callback.apply(_this, args);
        }, delay);
    };
    return throttled;
}
// 事件托管对象
var em = {
    fadeOutDone: [],
    trigger: function (eventName) {
        if (eventName in this) {
            while (this[eventName].length > 0) {
                var callback = this[eventName].shift();
                callback();
            }
        }
    }
};
// 回到顶部组件封装
var ScrollToTop = /** @class */ (function () {
    function ScrollToTop(selector, options) {
        var elem = document.querySelector(selector);
        if (elem == null) {
            console.error("没有捕捉到的DOM元素，请检查输入的字符串");
            return;
        }
        this.element = elem;
        this.options = _mixin(Object.create(null), ScrollToTop.defaultOptions, options);
        this.isHide = false;
        this.init();
    }
    // 初始化方法
    ScrollToTop.prototype.init = function () {
        this.hideElement();
        this.handleClick();
        this.handleScroll();
        this.setImg();
    };
    // 设置图片内容方法
    ScrollToTop.prototype.setImg = function () {
        if (this.options.imgSrc) {
            this.element.style.backgroundImage = "url(" + this.options.imgSrc + ")";
            this.element.style.backgroundSize = 'cover'; // 默认行为
        }
    };
    // 设置指针形状
    ScrollToTop.prototype.setCursor = function () {
        this.element.style.cursor = this.element.style.cursor ? "" : this.options.cursor;
    };
    // 隐藏当前元素方法
    ScrollToTop.prototype.hideElement = function () {
        this.isHide = true;
        __setOpacity(this.element, 0);
    };
    // 返回顶部方法
    ScrollToTop.prototype.backToTop = function () {
        var _this_1 = this;
        var timer = 0;
        _addClass(this.element, ScrollToTop.defaultStyle); // 添加过渡类样式
        // 将解除样式函数放置于事件管理器中，待动画完毕后触发
        em.fadeOutDone.push(_removeClass.bind(null, this.element, ScrollToTop.defaultStyle));
        var step = function () {
            var yDis = __getDocScrollValue().scrollY;
            if (yDis > 0) {
                document.body.scrollTop = document.documentElement.scrollTop =
                    yDis - _this_1.options.step;
                timer = requestAnimationFrame(step);
            }
            else {
                cancelAnimationFrame(timer);
                if (_this_1.options.callback) { // 触发回调函数
                    _this_1.options.callback();
                }
                ;
            }
        };
        timer = requestAnimationFrame(step);
    };
    // 处理滚动事件监听的淡入淡出效果
    ScrollToTop.prototype.handleScroll = function () {
        var _this_1 = this;
        var toggleStatus = _throttle(function () {
            // 控件出现
            if (__getDocScrollValue().scrollY > _this_1.options.showDis) {
                if (_this_1.isHide) {
                    __setFadeIn(_this_1.element, _this_1.options.fadeSpeed);
                    _this_1.setCursor(); // 出现时设置指针样式
                    _this_1.isHide = false;
                }
            }
            else { // 控件消失
                if (!_this_1.isHide) {
                    __setFadeOut(_this_1.element, _this_1.options.fadeSpeed);
                    _this_1.setCursor(); // 消失时移除指针样式
                    _this_1.isHide = true;
                }
            }
        }, this.options.delayTime);
        window.addEventListener("scroll", toggleStatus);
    };
    // 处理点击事件监听
    ScrollToTop.prototype.handleClick = function () {
        this.element.addEventListener("click", this.backToTop.bind(this)); // 绑定this指针指向实例
    };
    ScrollToTop.version = "0.0.4";
    ScrollToTop.defaultStyle = 'scroll-to-top-transition';
    ScrollToTop.defaultOptions = {
        showDis: 100,
        fadeSpeed: 20,
        step: 200,
        delayTime: 200,
        cursor: 'pointer'
    };
    return ScrollToTop;
}());
